﻿using mozhi.smarterp.Business.Enums;
using mozhi.smarterp.Business.Sales.Repositories;
using mozhi.smarterp.Business.Sales.Services;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;

namespace mozhi.smarterp.Business.Sales.Quotations
{
    public class SaleQuotationAppService : BusinessAppService, ISaleQuotationAppService
    {
        private ISaleQuotationRepository _reposiotry;
        private SaleQuotationManager _manager;

        public SaleQuotationAppService(ISaleQuotationRepository reposiotry, SaleQuotationManager manager)
        {
            _reposiotry = reposiotry;
            _manager = manager;
        }

        public async Task<SaleQuotationDto> CreateAsync(SaleQuotationCreateDto input)
        {
            var quotation = await _manager.GetAsync(null, input.Date, input.IncludeTax, input.CustomerId, input.Address, input.CurrencyId, input.ExchangeRate, input.DepartmentId, input.SalePersonId, input.EffectiveDate,
                input.ExpirationDate, input.Comment, input.Type);

            input.Items = input.Items ?? new List<SaleQuotationCreateItemDto>();

            var quotationItems = new List<SaleQuotationItem>();

            foreach (var item in input.Items)
            {
                var quotationItem = await _manager.GetItemAsync(null, item.ProductId, item.SaleUnitId, item.SaleQuantity, item.Price, item.TaxRateId, item.IsGift, item.Remark);

                quotationItems.Add(quotationItem);
            }

            quotation.ChangeItems(quotationItems);

            quotation = await _reposiotry.InsertAsync(quotation);

            var result = ObjectMapper.Map<SaleQuotation, SaleQuotationDto>(quotation);

            return result;
        }

        public async Task DeleteAsync(Guid id)
        {
            await _manager.DeleteAsync(id);
        }

        public async Task<SaleQuotationDto> GetAsync(Guid id)
        {
            var quotation = await _reposiotry.GetAsync(id);

            quotation = await _reposiotry.InsertAsync(quotation);

            var result = ObjectMapper.Map<SaleQuotation, SaleQuotationDto>(quotation);

            return result;
        }

        public async Task<PagedResultDto<SaleQuotationDto>> GetListAsync(SaleQuotationPagedResultRequestDto filter)
        {
            var quotations = await _reposiotry.GetPagedListAsync(filter.Keyword, filter.Number, filter.CustomerId, filter.CurrencyId, filter.SkipCount, filter.MaxResultCount, filter.Sorting, filter.IncludeDetails);

            var count = await _reposiotry.GetCountAsync(filter.Keyword, filter.Number, filter.CustomerId, filter.CurrencyId, null);

            var items = ObjectMapper.Map<List<SaleQuotation>, List<SaleQuotationDto>>(quotations);

            return new PagedResultDto<SaleQuotationDto> { Items = items, TotalCount = count };
        }

        public async Task<Guid> PushSaleOrderAsync(Guid id)
        {
            var orderId = await _manager.PushOrderAsync(id);

            return orderId;
        }

        public async Task<SaleQuotationDto> UpdateAsync(SaleQuotationUpdateDto input)
        {
            var quotation = await _manager.GetAsync(input.Id, input.Date, input.IncludeTax, input.CustomerId, input.Address, input.CurrencyId, input.ExchangeRate, input.DepartmentId, input.SalePersonId, input.EffectiveDate,
                 input.ExpirationDate, input.Comment, input.Type);

            input.Items = input.Items ?? new List<SaleQuotationUpdateItemDto>();

            var quotationItems = new List<SaleQuotationItem>();

            foreach (var item in input.Items)
            {
                var quotationItem = await _manager.GetItemAsync(null, item.ProductId, item.SaleUnitId, item.SaleQuantity, item.Price, item.TaxRateId, item.IsGift, item.Remark);

                quotationItems.Add(quotationItem);
            }

            quotation.ChangeItems(quotationItems);

            quotation = await _reposiotry.InsertAsync(quotation);

            var result = ObjectMapper.Map<SaleQuotation, SaleQuotationDto>(quotation);

            return result;
        }

        public async Task<SaleQuotationDto> UpdateStatusAsync(Guid id, DocumentStatusType status)
        {
            var quotation = await _manager.UpdateStatusAsync(id, status);

            await _reposiotry.UpdateAsync(quotation);

            var result = ObjectMapper.Map<SaleQuotation, SaleQuotationDto>(quotation);

            return result;
        }
    }
}
